FNISVGEditorWindow = Class.create(GUIComponent, {
  initialize: function($super, editorInstance, options) {
    $super(options);
    this._editorInstance = editorInstance;
    this._iframeLoadListener = this._onIframeLoad.bindAsEventListener(this);
    this.domNode = new Element('iframe', {frameBorder: 0, scrolling: 'no', border: 0, className: "fniSVGEditorWindow", src: this._editorInstance.getBasePath() + '/window/window.html'});
    this.domNode.setStyle({
      opacity: 0,
      border: 0
    });      
    
    Event.observe(this.domNode, "load", this._iframeLoadListener);    
  },
  _onIframeLoad: function (event) {
    this._frameDocument = this.domNode.contentDocument;
    this._frameWindow = this._frameDocument.parentWindow;
    if (!this._frameWindow)
      this._frameWindow = this._frameDocument.defaultView;
    
    this._contentElement = this._frameDocument.getElementById('fniSVGEditorWindowContent');
    
    var options = this.getComponentOptions();
    
    var headElement = this._frameDocument.getElementsByTagName('head')[0];
    
    /* we need to import prototype.js from original document */
    var editorScripts = document.getElementsByTagName("script"); 
    for (var i = 0; i < editorScripts.length; i++) {
      var src = editorScripts[i].src;
      if (src && (src.endsWith("/prototype.js"))) {
        var scriptURL = this._editorInstance._resolveRelativePath(window.location.href, src);
        var scriptElement = null;
        if (Prototype.Browser.IE) {
          scriptElement = this._frameDocument.createElement('<script type="text/javascript" src="' + scriptURL + "/>");          
        } else {
          scriptElement = this._frameDocument.createElement("script");
          scriptElement.type = "text/javascript";
          scriptElement.src = scriptURL;
        }        
        
        headElement.appendChild(scriptElement);
      }
    }
    
    var linkElement = document.createElement("link");
    linkElement.rel = 'stylesheet';
    linkElement.href = this._editorInstance.getBasePath() + "/window/window.css";
    headElement.appendChild(linkElement);
    
    if (options.customCSS) {
      var linkElement = document.createElement("link");
      linkElement.rel = 'stylesheet';
      linkElement.href = options.customCSS;
      headElement.appendChild(linkElement);
    }
    
    this._titleBarElement = this._frameDocument.getElementById("fniSVGEditorWindowTitleBar");
    
    if (options.title) {
      this._titleElement = this._frameDocument.createElement("div");
      this._titleElement.id = "fniSVGEditorWindowTitle";
      this._titleButtons = this._frameDocument.createElement("div");
      this._titleButtons.id = "fniSVGEditorWindowTitleButtons";
      this._iconElement = this._frameDocument.createElement("div");
      this._iconElement.id = "fniSVGEditorWindowIcon";
      
      this._titleElementMouseDownListener = this._onTitleElementMouseDown.bindAsEventListener(this);
  	  Event.observe(this._titleElement, "mousedown", this._titleElementMouseDownListener);
      
  	  this._titleBarElement.appendChild(this._iconElement);
  	  this._titleBarElement.appendChild(this._titleElement);
  	  this._titleBarElement.appendChild(this._titleButtons);
        
      if (options.iconURL) 
        this.setIconURL(options.iconURL);
      
      this.setTitle(options.title);
	  
	  this.disableSelection(this._titleElement);
    } else {
      this._titleBarElement.parentNode.removeChild(this._titleBarElement);
    }
    
    var _this = this;
    
    if (options.contentURL) {
      new Ajax.Request(options.contentURL, {  
        onSuccess: function(transport){
          _this.getContentElement().innerHTML = transport.responseText;
          _this._ready();
        },
        onFailure: function(transport){
          alert("Error while loading window content: " + transport.responseText);
        }
      });
    } else {    
      this._ready();
    }
  },
  _ready: function () {
    if (this.getContentElement().hasClassName) {
      this.fire("onLoad", {});
    } else
      setTimeout("getComponentById(" + this.getComponentId() + ")._ready();", 10); 
  },
  addContentComponent: function (component) {
    this.addGUIComponent(this.getContentElement(), component);
  },
  setTitle: function (title) {
    this._titleElement.innerHTML = title;
  },
  getTitle: function () {
    return this._titleElement.innerHTML;
  },
  getContentElement: function () {
    return $(this._contentElement);
  },
  setIconURL: function (iconURL) {
    this._iconElement.style.backgroundImage = 'url(' + iconURL + ')';
  },
  close: function () {
    this.fire("closing", {});    
    this.domNode.parentNode.removeChild(this.domNode);    
    this.deinitialize();
  },
  getFrameDocument: function () {
    return this._frameDocument;
  },
  getFrameWindow: function () {
    return this._frameWindow;
  },
  center: function () {
    var windowDims = Element.getDimensions(this.domNode);
    var left = ((document.viewport.getWidth()) / 2 - (windowDims.width / 2)) + 'px';
    var top = ((document.viewport.getHeight()) / 2 - (windowDims.height / 2)) + 'px';     
    
    this.domNode.setStyle({
      left: left,
      top: top
    });    
  },
  show: function () {
    this.domNode.setStyle({
      opacity: 1
    });
  },
  localize: function () {
    var children = this.getContentElement().childNodes;
    for (var i = 0; i < children.length; i++) {
      if (children[i].nodeType == 1)
        this._localizeE(children[i])
    }
  },
  setHeight: function (height) {
    this.domNode.setStyle({
      height: height + 'px'
    });
  },
  setWidth: function (width) {
    this.domNode.setStyle({
      width: width + 'px'
    });
  },
  autoHeight: function () {
    var cE = this.getContentElement();
    var height = cE.getLayout().get('height');
    height += cE.getLayout().get('margin-top') + cE.getLayout().get('margin-bottom');
    var tb = $(this._titleBarElement);
    
    height += tb.getLayout().get('height');
    height += tb.getLayout().get('margin-top') + tb.getLayout().get('margin-bottom');
    height += tb.getLayout().get('padding-top') + tb.getLayout().get('padding-bottom');
    
    this.domNode.setStyle({
      height: height + 'px'
    });
  },
  setZIndex: function (zIndex) {
    this.domNode.setStyle({
      zIndex: zIndex
    }); 
  },
  _localizeE: function (e) {
    var children = e.childNodes;
    for (var i = 0; i < children.length; i++) {
      if (children[i].nodeType == 1)
        this._localizeE(children[i])
    }
    
    if (e.hasAttribute("fni:locale")) {
      var text = SVGLocale.getText(e.getAttribute("fni:locale"));
      if ((e.tagName == 'INPUT') && (e.type == 'submit')) 
        e.value = text;
      else 
        e.innerHTML = text;
    }
  },
  _onTitleElementMouseDown: function (event) {
    if (this._isDragging != true) {
      this._isDragging = true;
      
      this._documentMouseMoveListener = this._onDocumentMouseMove.bindAsEventListener(this);
      this._documentMouseUpListener = this._onDocumentMouseUp.bindAsEventListener(this);
      this._frameDocumentMouseMoveListener = this._onFrameDocumentMouseMove.bindAsEventListener(this);
      
      Event.observe(document, "mousemove", this._documentMouseMoveListener);
      Event.observe(document, "mouseup", this._documentMouseUpListener);   
      Event.observe(this.getFrameDocument(), "mousemove", this._frameDocumentMouseMoveListener);
      Event.observe(this.getFrameDocument(), "mouseup", this._documentMouseUpListener);
      
      this._lastX = Event.pointerX(event) + this.domNode.getLayout().get('left'); 
      this._lastY = Event.pointerY(event) + this.domNode.getLayout().get('top');
    }
  },
  _onDocumentMouseMove: function (event) {
	this._handleMove(Event.pointerX(event), Event.pointerY(event));
  },  
  _onFrameDocumentMouseMove: function (event) {
    
    this._handleMove(Event.pointerX(event) + this.domNode.getLayout().get('left'), Event.pointerY(event) + this.domNode.getLayout().get('top'));
  },
  _handleMove: function (pointerX, pointerY) {
	var xDiff = pointerX - this._lastX; 
	var yDiff = pointerY - this._lastY;
	  
	this.domNode.setStyle({
      top: (this.domNode.getLayout().get('top') + yDiff) + 'px',
      left: (this.domNode.getLayout().get('left') + xDiff) + 'px'
    });
    
    this._lastX += xDiff;
    this._lastY += yDiff;
  },
  _onDocumentMouseUp: function (event) {
    if (this._isDragging == true) {
      this._isDragging = false;
      Event.stopObserving(document, "mousemove", this._documentMouseMoveListener);
      Event.stopObserving(document, "mouseup", this._documentMouseUpListener);
      Event.stopObserving(this.getFrameDocument(), "mousemove", this._frameDocumentMouseMoveListener);
      Event.stopObserving(this.getFrameDocument(), "mouseup", this._documentMouseUpListener);
    }
  }
});

FNIFNISVGEditorDialogStack = {
  push: function (dialog) {    
    dialog.setZIndex(this._gpZIndex + 1);
    
    if (this._stack.length > 0) {
      for (var i = 0; i < this._stack.length; i++) {
        this._stack[i].setZIndex(this._gpZIndex - (this._stack.length - i));
      }
    } else {
      this._addGlassPane();
    }
    
    this._stack.push(dialog);
  },
  remove: function (dialog) {
    if (this._stack[this._stack.length - 1] == dialog) {
      this._stack.pop();

      if (this._stack.length > 0) {
        this._stack[this._stack.length - 1].setZIndex(this._gpZIndex + 1);
      } else {
        this._removeGlassPane();
      }
    } else {
      for (var i = 0; i < this._stack.length; i++) {
        if (this._stack[i] == dialog)
          this._stack.splice(i, 1);
      }
    }
  },
  _removeGlassPane: function () {
    this._glassPane.remove(); 
    this._glassPane = null;
  },
  _addGlassPane: function () {
    if (Prototype.Browser.IE) {
      this._glassPane = new Element("iframe", {className: "fniSVGEditorGlassPane"});
      Event.observe(this._glassPane, "load", function (event) {
        var frame = Event.element(event);        
        /* TODO: Needs better solution */
        var backgroundColor = FNIFNISVGEditorDialogStack._getCSSRulePropertyValue(".fniSVGEditorGlassPane", "backgroundColor");
        if (!backgroundColor)
          backgroundColor = "#000";          
        frame.contentDocument.body.setAttribute("style", "background-color:" + backgroundColor);
      });
    } else {
      this._glassPane = new Element("div", {className: "fniSVGEditorGlassPane"});
    }
    
    this._glassPane.setStyle({
      zIndex: this._gpZIndex
    });
    
    document.getElementsByTagName('body')[0].appendChild(this._glassPane);    
  },
  _getCSSRulePropertyValue: function (cssRule, property) {
    var stylesheets = document.styleSheets;
    
    for (var i = 0; i < stylesheets.length; i++) {
      var stylesheet = stylesheets[i];
      var rules = stylesheet.rules ? stylesheet.rules : stylesheet.cssRules;
      for (var j = 0; j < rules.length; j++) {
        var rule = rules[j];
        if (rule.selectorText == cssRule)
          return rule.style[property];
      }
    } 
  },
  _stack: new Array(),
  _gpZIndex: 99, 
  _glassPane: null
};

FNISVGEditorDialog = Class.create(FNISVGEditorWindow, {
  show: function ($super) {
    $super();
    FNIFNISVGEditorDialogStack.push(this);    
  },
  hide: function ($super) {
    FNIFNISVGEditorDialogStack.remove(this);    
    $super();
  },
  close: function ($super) {
    FNIFNISVGEditorDialogStack.remove(this);    
    $super();
  }
});